package com.mxm.mirai.web;

import com.mxm.mirai.dao.Mail;
import com.mxm.mirai.dao.Msg;
import com.mxm.mirai.dao.Table_Json;
import com.mxm.mirai.dao.User;
import com.mxm.mirai.jwt.JWTUtil;
import com.mxm.mirai.service.MailService;
import com.mxm.mirai.service.impl.UserServiceImpl;
import com.mxm.mirai.tools.BotTools;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@Api(value = "测试Web")
public class UserWeb {

    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private MailService mailService;

    @Value("classpath:templates/mould/templateA.html")
    private Resource templateA;

    private static Mail mail;
    private static BotTools botTools = new BotTools();
    private static User user = null;
    private static Map<String,Object> maps= null;

    @ApiOperation(value = "用户登录", notes = "登录--不进行拦截")
    @PostMapping("/loginuser")
    public Msg login(String username, String password,String captcha) {
        String sessionCaptcha = (String) SecurityUtils.getSubject().getSession().getAttribute(CaptchaWeb.KEY_CAPTCHA);
        System.out.println("对比验证码，生成到session里的验证码:"+sessionCaptcha+" 前台输入的验证码:"+captcha);
        if (null == captcha || !captcha.equalsIgnoreCase(sessionCaptcha)) {
            return Msg.fail().add("info","验证码错误");
        }
        String realPassword = userService.getPassword(username);
        if (realPassword == null) {
            return Msg.fail().add("info","用户名错误");
        } else if (!realPassword.equals(password)) {
            return Msg.fail().add("info","密码错误");
        } else {
            return Msg.success().add("token", JWTUtil.createToken(username));
        }
    }
    @ApiOperation(value = "用户注册", notes = "注册--不进行拦截")
    @PostMapping("/registeruser")
    public Msg register(String username,String password, String captcha, HttpServletRequest request) {
        String sessionCaptcha = (String) SecurityUtils.getSubject().getSession().getAttribute(CaptchaWeb.KEY_CAPTCHA);
        System.out.println("对比验证码，生成到session里的验证码:"+sessionCaptcha+" 前台输入的验证码:"+captcha);
        if (null == captcha || !captcha.equalsIgnoreCase(sessionCaptcha)) {
            return Msg.fail().add("info","验证码错误");
        }
        Integer ban = userService.checkUserBanStatus(username);
        if (ban!=null && ban==1){
            return Msg.fail().add("info","用户已存在,并未激活");
        }
        if(userService.getUserByUsernameCount(username)>0){
            return Msg.fail().add("info","用户已存在");
        }
        StringBuffer url = request.getRequestURL();
        String contextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append("/").toString();
        mail = mailService.SelectMail();
        String uuid = botTools.UUID_();
        String html="<h2>点击以下链接认证激活:<h2><br>"+contextUrl+"openUser?other="+uuid;
        try {
            String timeStr= LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            html = IOUtils.toString(templateA.getInputStream(), Charset.forName("UTF-8")).replace("[邮箱]",username)
                    .replace("[激活URL]",contextUrl+"openUser?other="+uuid)
                    .replace("[时间]",timeStr);
        } catch (IOException e) {
        }
        if(botTools.ToMail(mail.getSmtp(),mail.getNumber(),mail.getPassword(),mail.getPort(),"Cat",username,"Bot代挂",html)){
            user = new User();
            user.setUsername(username);
            user.setPassword(password);
            user.setQuota(1);
            user.setOther(uuid);
            user.setRole("user");
            user.setPermission("normal");
            user.setBan(1);//冻结
            Date time = new Date();
            Calendar cal = Calendar.getInstance();
            cal.setTime(time);//设置起时间
            cal.add(Calendar.DATE, 30);//增加30天
            user.setRegistertime(time);
            user.setDuedate(cal.getTime());
            userService.AddUser(user);
            return Msg.success().add("msg","注册成功,请到邮件激活账户");
        }else {
            return Msg.fail().add("info","账户激活邮件发送失败,请稍后再试");
        }
    }
    @GetMapping("/openUser")
    @ApiOperation(value = "用户激活", notes = "激活--不进行拦截")
    public String openUser(String other){
        try {
            String username = userService.SelectOtherByUsername(other);
            Integer ban = userService.checkUserBanStatus(username);
            if(ban!=null && ban==0){
                return "<script>alert(\"请勿重复激活！\");window.location = '/login';</script>";
            }
            if(username!=null && !"".equals(username)){
                userService.openUser(username);
                userService.UpdateUsernameByOther(username,"激活成功");
                return "<script>alert(\"激活成功！\");window.location = '/login';</script>";
            }
            return "<script>alert(\"激活失败！\");window.location = '/';</script>";
        }catch (Exception e){
            e.printStackTrace();
            return "<script>alert(\"激活失败！\");window.location = '/';</script>";
        }
    }
    @PostMapping("/UpdatePassword")
    @RequiresRoles(logical = Logical.OR, value = {"user"})
    @ApiOperation(value = "用户密码更改", notes = "更改--进行拦截")
    public Map UpdatePassword(String oldpassword,String newpassword,HttpServletRequest request){
        String name = JWTUtil.getUsername(request.getHeader("token"));
        user = userService.getUserByUsername(name);
        maps = new HashMap();
        if(user==null){
            maps.put("state",500);
            maps.put("msg","没能查到本用户！");
            return maps;
        }
        if(!oldpassword.equals(user.getPassword())){
            maps.put("state",500);
            maps.put("msg","旧密码错误！");
            return maps;
        }
        if(userService.UpdatePassword(name,newpassword)>=0){
            maps.put("state",200);
            maps.put("msg","更换密码成功！");
            return maps;
        }
        maps.put("state",500);
        maps.put("msg","更换密码失败！");
        return maps;
    }
    @GetMapping("/SelectUserByUsername")
    @RequiresRoles(logical = Logical.OR, value = {"user"})
    @ApiOperation(value = "用户信息", notes = "拥有 user 权限可以访问该页面")
    public User SelectUserByUsername(HttpServletRequest request){
        String name = JWTUtil.getUsername(request.getHeader("token"));
        return userService.SelectUserByUsername(name);
    }

    @ApiOperation(value = "无权限", notes = "无权限跳转的接口")
    @RequestMapping(path = "/unauthorized/{message}")
    public Msg unauthorized(@PathVariable String message) throws UnsupportedEncodingException {
        return Msg.fail().add("info",message);
    }

    //==============================================admin===================================================
    @GetMapping("/SelectUserListPage")
    @ApiOperation(value = "用户翻页查询", notes = "拥有 admin 权限可以访问该页面")
    @RequiresRoles(logical = Logical.OR, value = {"admin"})
    public Table_Json SelectUserListPage(String username, Integer page, Integer limit) {
        return userService.SelectUserListPage(username,page,limit);
    }
    @PostMapping("/AddUser")
    @RequiresRoles(logical = Logical.OR, value = {"admin"})
    @ApiOperation(value = "用户添加", notes = "拥有 admin 权限可以访问该页面")
    public Integer AddUser(String username,String passwrod){
        Integer ban = userService.checkUserBanStatus(username);
        if (ban!=null && ban==1){
            return 1;
        }
        user = new User();
        user.setUsername(username);
        user.setPassword(passwrod);
        user.setRole("user");
        user.setRegistertime(new Date());
        user.setBan(1);
        if(userService.AddUser(user)>=1){
            return 0;
        }
        return 1;
    }
    @PostMapping("/DeleteUser")
    @RequiresRoles(logical = Logical.OR, value = {"admin"})
    @ApiOperation(value = "用户删除", notes = "拥有 admin 权限可以访问该页面")
    public Integer DeleteUser(Integer id){
        if(userService.DeleteUser(id)>=0){
            return 0;
        }
        return 1;
    }
    @PostMapping("/UpdateUser")
    @RequiresRoles(logical = Logical.OR, value = {"admin"})
    @ApiOperation(value = "用户更新", notes = "拥有 admin 权限可以访问该页面")
    public Integer UpdateUser(@RequestBody User user){
        if(userService.UpdateUser(user)>=0){
            return 0;
        }
        return 1;
    }
    @PostMapping("/UpdateUserBanInversion")
    @RequiresRoles(logical = Logical.OR, value = {"admin"})
    @ApiOperation(value = "用户状态切换", notes = "拥有 admin 权限可以访问该页面")
    public Integer UpdateUserBanInversion(Integer id){
        if(userService.UpdateUserBanInversion(id)>=0){
            return 0;
        }
        return 1;
    }






    //admin或user或vip权限的可访问
    @ApiOperation(value = "特定用户访问", notes = "拥有 user, admin 角色的用户可以访问下面的页面")
    @PostMapping("/getMessage")
    @RequiresRoles(logical = Logical.OR, value = {"user", "admin"})
    public Msg getMessage() {
        return Msg.success().add("info","成功获得信息！");
    }

    //admin或vip权限的可访问
    @ApiOperation(value = "Vip用户访问", notes = "拥有 vip 权限可以访问该页面")
    @PostMapping("/getVipMessage")
    @RequiresRoles(logical = Logical.OR, value = {"user", "admin"})//角色
    @RequiresPermissions("vip")//权限
    public Msg getVipMessage() {
        return Msg.success().add("info","成功获得 vip 信息！");
    }

    //admin权限的可访问
    @ApiOperation(value = "admin用户访问", notes = "拥有 admin 权限可以访问该页面")
    @PostMapping("/getAdminMessage")
    @RequiresRoles(logical = Logical.OR, value = {"admin"})
    public Msg getAdminMessage() {
        return Msg.success().add("info","成功获得 管理员 信息！");
    }

}